home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- * canmisc -
- * Miscellaneous operations.
- *
- * Paul Haeberli - 1991
- *
- * exports
- *
- void onefield(c,fieldno);
- void fieldfilter(c,thresh);
- void blendcanvas(a,b,c,f);
- void diffcanvas(a,b,c);
- *
- */
- #include "stdio.h"
- #include "canvas.h"
- #include "math.h"
- #include "lum.h"
-
- void onefield(c,fieldno)
- canvas *c;
- int fieldno;
- {
- int y ,sy1, sy2, n;
- unsigned char *sptr1, *sptr2, *dptr;
-
- fieldno &= 1;
- fieldno ^= 1;
- for(y=fieldno; y<c->ysize; y+=2) {
- sy1 = y-1;
- sy2 = y+1;
- if(sy1<0) sy1 = 0;
- if(sy1>=c->ysize) sy1 = c->ysize-1;
- if(sy2<0) sy2 = 0;
- if(sy2>=c->ysize) sy2 = c->ysize-1;
- sptr1 = (unsigned char *)(c->data+sy1*c->xsize);
- sptr2 = (unsigned char *)(c->data+sy2*c->xsize);
- dptr = (unsigned char *)(c->data+y*c->xsize);
- n = c->xsize;
- while(n--) {
- dptr[OFFSET_R] = (sptr1[OFFSET_R]+sptr2[OFFSET_R])/2;
- dptr[OFFSET_G] = (sptr1[OFFSET_G]+sptr2[OFFSET_G])/2;
- dptr[OFFSET_B] = (sptr1[OFFSET_B]+sptr2[OFFSET_B])/2;
- dptr += 4;
- sptr1 += 4;
- sptr2 += 4;
- }
- }
- }
-
- void fieldfilter(c,thresh)
- canvas *c;
- int thresh;
- {
- int y ,sy1, sy2, n, lum, lum1, lum2, dl, lumlow, lumhi;
- unsigned char *sptr1, *sptr2, *dptr;
-
- for(y=0; y<c->ysize; y+=2) {
- sy1 = y-1;
- sy2 = y+1;
- if(sy1<0) sy1 = 0;
- if(sy1>=c->ysize) sy1 = c->ysize-1;
- if(sy2<0) sy2 = 0;
- if(sy2>=c->ysize) sy2 = c->ysize-1;
- sptr1 = (unsigned char *)(c->data+sy1*c->xsize);
- sptr2 = (unsigned char *)(c->data+sy2*c->xsize);
- dptr = (unsigned char *)(c->data+y*c->xsize);
- n = c->xsize;
- while(n--) {
- lum1 = ILUM(sptr1[OFFSET_R],sptr1[OFFSET_G],sptr1[OFFSET_B]);
- lum2 = ILUM(sptr2[OFFSET_R],sptr2[OFFSET_G],sptr2[OFFSET_B]);
- lum = ILUM(dptr[OFFSET_R],dptr[OFFSET_G],dptr[OFFSET_B]);
- if(lum2>lum1) {
- lumlow = lum1-thresh;
- lumhi = lum2+thresh;
- } else {
- lumlow = lum2-thresh;
- lumhi = lum1+thresh;
- }
- if(lum<lumlow || lum>lumhi) {
- dptr[OFFSET_R] = (sptr1[OFFSET_R]+sptr2[OFFSET_R])/2;
- dptr[OFFSET_G] = (sptr1[OFFSET_G]+sptr2[OFFSET_G])/2;
- dptr[OFFSET_B] = (sptr1[OFFSET_B]+sptr2[OFFSET_B])/2;
- }
- dptr += 4;
- sptr1 += 4;
- sptr2 += 4;
- }
- }
- }
-
- #define BLERP(v1,v2,a) ( (v1)+ (((((v2)-(v1))*(a))+127)>>8) )
-
- void blendcanvas(a,b,c,f)
- canvas *a, *b, *c;
- float f;
- {
- unsigned char *aptr, *bptr, *cptr;
- unsigned long *laptr, *lbptr, *lcptr;
- short aa, v;
- int n;
-
- saverect(c,&c->area);
- if((a->xsize != b->xsize) || (a->ysize != b->ysize) ||
- (a->xsize != c->xsize) || (a->ysize != c->ysize) ) {
- fprintf(stderr,"blendcanvas: all canvases must be the same size\n");
- return;
- }
- aa = 256*f;
- laptr = a->data;
- lbptr = b->data;
- lcptr = c->data;
- n = a->xsize*a->ysize;
- if(f>=0.0 && f<= 1.0) {
- while(n--) {
- if(*laptr == *lbptr) {
- *lcptr = *laptr;
- } else {
- aptr = (unsigned char *)laptr;
- bptr = (unsigned char *)lbptr;
- cptr = (unsigned char *)lcptr;
- cptr[OFFSET_R] = BLERP(aptr[OFFSET_R],bptr[OFFSET_R],aa);
- cptr[OFFSET_G] = BLERP(aptr[OFFSET_G],bptr[OFFSET_G],aa);
- cptr[OFFSET_B] = BLERP(aptr[OFFSET_B],bptr[OFFSET_B],aa);
- }
- laptr++;
- lbptr++;
- lcptr++;
- }
- } else {
- while(n--) {
- if(*laptr == *lbptr) {
- *lcptr = *laptr;
- } else {
- aptr = (unsigned char *)laptr;
- bptr = (unsigned char *)lbptr;
- cptr = (unsigned char *)lcptr;
- v = BLERP(aptr[OFFSET_R],bptr[OFFSET_R],aa);
- if(v&0xff00) {
- if(v<0) v = 0; else v = 255;
- }
- cptr[OFFSET_R] = v;
- v = BLERP(aptr[OFFSET_G],bptr[OFFSET_G],aa);
- if(v&0xff00) {
- if(v<0) v = 0; else v = 255;
- }
- cptr[OFFSET_G] = v;
- v = BLERP(aptr[OFFSET_B],bptr[OFFSET_B],aa);
- if(v&0xff00) {
- if(v<0) v = 0; else v = 255;
- }
- cptr[OFFSET_B] = v;
- }
- laptr++;
- lbptr++;
- lcptr++;
- }
- }
- touchcanvas(c);
- flushcanvas(c);
- }
-
- void diffcanvas(a,b,c)
- canvas *a, *b, *c;
- {
- unsigned char *aptr, *bptr, *cptr;
- short aa, v;
- int n;
-
- saverect(c,&c->area);
- if((a->xsize != b->xsize) || (a->ysize != b->ysize) ||
- (a->xsize != c->xsize) || (a->ysize != c->ysize) ) {
- fprintf(stderr,"diffcanvas: all canvases must be the same size\n");
- return;
- }
- aptr = (unsigned char *)a->data;
- bptr = (unsigned char *)b->data;
- cptr = (unsigned char *)c->data;
- n = a->xsize*a->ysize;
- while(n--) {
- v = 128+aptr[OFFSET_R]-bptr[OFFSET_R];
- if(v&0xff00) {
- if(v<0) v = 0; else v = 255;
- }
- cptr[OFFSET_R] = v;
- v = 128+aptr[OFFSET_G]-bptr[OFFSET_G];
- if(v&0xff00) {
- if(v<0) v = 0; else v = 255;
- }
- cptr[OFFSET_G] = v;
- v = 128+aptr[OFFSET_B]-bptr[OFFSET_B];
- if(v&0xff00) {
- if(v<0) v = 0; else v = 255;
- }
- cptr[OFFSET_B] = v;
- aptr += 4;
- bptr += 4;
- cptr += 4;
- }
- touchcanvas(c);
- flushcanvas(c);
- }
-